package com.zyy.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @Description: 类描述
 * @Author: zyy
 * @Date: 2022/10/08 17:31
 */

/**
 * 开启WebSecurity模式
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 授权
     * 定制请求的授权规则
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                //首页所有人可以访问
                .antMatchers("/").permitAll()
                //level1只有vip1可以访问
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //没有权限默认会跳转到默认登录页面
//        http.formLogin();
        //自定义登录页面
        http.formLogin()
                .loginPage("/toLogin")
                //配置接收登录的用户名和密码的参数  login 请求来到登录页
                .usernameParameter("name").passwordParameter("pwd").loginProcessingUrl("/login");
        //注销 注销成功后跳转到首页（不然默认跳转到登录页）
        http.logout().logoutSuccessUrl("/");
        //关闭csrf功能 不然点击注销可能会报（404）  跨站请求伪造,默认只能通过post方式提交logout请求
        http.csrf().disable();
        //记住我
        http.rememberMe().rememberMeParameter("remember");
    }

    /**
     * 认证
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在内存中定义，也可以在jdbc中去拿....
        //Spring security 5.0中新增了多种加密方式，也改变了密码的格式。
        //要想我们的项目还能够正常登陆，需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
        //spring security 官方推荐的是使用bcrypt加密方式。
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip2", "vip3")
                .and()
                .withUser("zyy").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");

    }
}
